import React, {createRef} from "react";
import Board from "./Board";
import "./Game.scss"

function GameInfo(props) {
    return <div className="game-info">
        <p>
            <span>next: {props.xIsNext ? "X" : "O"}</span>
            <span>&nbsp;&nbsp;&nbsp;</span>
            <span>winner: {props.winner || "none"}</span>
        </p>
        <button
            onClick={props.resetBoard}
            style={{marginBottom: "10px"}}
        >
            reset
        </button>
    </div>
}

function GameHistory(props) {
    return <ol className="game-history">
        {props.history.map((value, index) =>
            <li key={index}>
                <button
                    onClick={() => props.handleGoBack(index)}
                    onMouseEnter={() => props.handleMouseEnter(value)}
                    onMouseLeave={() => props.handleMouseLeave(value)}
                >
                    <span>{"undo step " + (index + 1)}</span>
                    <span>{", at row " + (value.row + 1)}</span>
                    <span>{" col " + (value.col + 1)}</span>
                </button>
            </li>
        )}
    </ol>
}

class Game extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            history: [], // col,row
            squares: Array(9).fill(null),
            xIsNext: true,
            winner: null
        }
        this.Board = createRef()
    }

    render() {
        return <div className="game-area">
            <div className="left-area">
                <GameInfo
                    xIsNext={this.state.xIsNext}
                    winner={this.state.winner}
                    resetBoard={this.resetBoard}
                />
                <Board
                    squares={this.state.squares}
                    handleSquareClick={this.handleSquareClick}
                    ref={this.Board}
                />
            </div>
            <div className="right-area">
                <GameHistory
                    history={this.state.history}
                    handleGoBack={this.handleGoBack}
                    handleMouseEnter={this.handleHistoryMouseEnter}
                    handleMouseLeave={this.handleHistoryMouseLeave}
                />
            </div>
        </div>
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        if (this.state.winner) {
            window.setTimeout(() => {
                alert("winner: " + this.state.winner)
            }, 0)
        }
    }

    handleSquareClick = (i) => {
        if (this.state.squares[i] === null && !this.state.winner) {
            let squares = this.state.squares.slice()
            squares[i] = {
                value: this.state.xIsNext ? "X" : "O",
                active: false
            }
            let current = {
                col: i % 3,
                row: Math.floor(i / 3)
            }
            let history = this.state.history.concat([current])
            // debugger
            let line = this.calculateWinner(squares)
            let winner = null
            if (line !== null) {
                winner = squares[line[0]].value
                line.forEach((i) => {
                    squares[i].active = true
                })
            } else if (this.isFull(squares)) {
                winner = "draw"
            }
            this.setState({
                squares: squares,
                xIsNext: !this.state.xIsNext,
                winner: winner,
                history: history
            })
        }
    }

    handleHistoryMouseEnter = ({row, col}) => {
        let index = row * 3 + col
        if (this.state.squares[index] === null || this.state.winner) {
            return
        }
        let squares = this.state.squares
        squares[index].active = true
        this.setState({
            squares: squares
        })
    }

    handleHistoryMouseLeave = ({row, col}) => {
        let index = row * 3 + col
        if (this.state.squares[index] === null || this.state.winner) {
            return
        }
        let squares = this.state.squares
        squares[index].active = false
        this.setState({
            squares: squares
        })
    }

    handleGoBack = (step) => {
        if (this.state.winner) {
            return
        }
        let newSquares = this.state.squares
        for (let i = this.state.history.length - 1; i >= step; --i) {
            let {row, col} = this.state.history[i]
            let index = row * 3 + col
            newSquares[index] = null
        }
        let xIsNext = step % 2 === 0
        let newHistory = this.state.history.slice(0, step)
        this.setState({
            squares: newSquares,
            xIsNext: xIsNext,
            history: newHistory
        })
    }

    resetBoard = () => {
        this.setState({
            history: [],
            squares: Array(9).fill(null),
            xIsNext: true,
            winner: null
        })
    }

    isFull = (squares) => {
        for (let square of squares) {
            if (!square) {
                return false
            }
        }
        return true
    }

    calculateWinner = (squares) => {
        const lines = [
            [0, 1, 2],
            [3, 4, 5],
            [6, 7, 8],
            [0, 3, 6],
            [1, 4, 7],
            [2, 5, 8],
            [0, 4, 8],
            [2, 4, 6],
        ];
        for (let i = 0; i < lines.length; i++) {
            const [a, b, c] = lines[i];
            if (squares[a] && squares[b] && squares[c] &&
                squares[a].value === squares[b].value &&
                squares[a].value === squares[c].value
            ) {
                // return squares[a];
                return [a, b, c]
            }
        }
        return null;
    }
}

export default Game
